using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace Lzfy_His_Service.Logging
{
    /// <summary>
    /// 企业微信日志扩展
    /// </summary>
    public static class WeChatLoggingExtensions
    {
        #region 登录相关日志

        /// <summary>
        /// 记录登录成功日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="userId">用户ID</param>
        /// <param name="clientIp">客户端IP</param>
        /// <param name="userAgent">用户代理</param>
        public static void LogLoginSuccessful(this ILogger logger, string userId, string clientIp, string? userAgent = null)
        {
            logger.LogInformation("企业微信登录成功 - 用户ID: {UserId}, 客户端IP: {ClientIp}, 用户代理: {UserAgent}", 
                userId, clientIp, userAgent ?? "未知");
        }

        /// <summary>
        /// 记录登录失败日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="reason">失败原因</param>
        /// <param name="clientIp">客户端IP</param>
        /// <param name="userId">用户ID（可选）</param>
        /// <param name="userAgent">用户代理</param>
        public static void LogLoginFailed(this ILogger logger, string reason, string clientIp, string? userId = null, string? userAgent = null)
        {
            logger.LogWarning("企业微信登录失败 - 原因: {Reason}, 用户ID: {UserId}, 客户端IP: {ClientIp}, 用户代理: {UserAgent}", 
                reason, userId ?? "未知", clientIp, userAgent ?? "未知");
        }

        /// <summary>
        /// 记录登录尝试日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="authCode">授权码（脱敏）</param>
        /// <param name="clientIp">客户端IP</param>
        /// <param name="userAgent">用户代理</param>
        public static void LogLoginAttempt(this ILogger logger, string authCode, string clientIp, string? userAgent = null)
        {
            var maskedCode = MaskSensitiveData(authCode);
            logger.LogInformation("企业微信登录尝试 - 授权码: {AuthCode}, 客户端IP: {ClientIp}, 用户代理: {UserAgent}", 
                maskedCode, clientIp, userAgent ?? "未知");
        }

        #endregion

        #region API调用日志

        /// <summary>
        /// 记录API调用开始日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="apiName">API名称</param>
        /// <param name="parameters">参数（可选）</param>
        /// <param name="memberName">调用方法名</param>
        /// <param name="sourceFilePath">源文件路径</param>
        /// <param name="sourceLineNumber">源代码行号</param>
        public static void LogApiCallStart(this ILogger logger, string apiName, object? parameters = null,
            [CallerMemberName] string memberName = "",
            [CallerFilePath] string sourceFilePath = "",
            [CallerLineNumber] int sourceLineNumber = 0)
        {
            logger.LogDebug("开始调用企业微信API - API: {ApiName}, 参数: {Parameters}, 调用方法: {MemberName}, 文件: {SourceFile}:{LineNumber}", 
                apiName, parameters, memberName, Path.GetFileName(sourceFilePath), sourceLineNumber);
        }

        /// <summary>
        /// 记录API调用成功日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="apiName">API名称</param>
        /// <param name="duration">耗时</param>
        /// <param name="responseSize">响应大小（字节）</param>
        public static void LogApiCallSuccess(this ILogger logger, string apiName, TimeSpan duration, long? responseSize = null)
        {
            logger.LogInformation("企业微信API调用成功 - API: {ApiName}, 耗时: {Duration}ms, 响应大小: {ResponseSize}字节", 
                apiName, duration.TotalMilliseconds, responseSize ?? 0);
        }

        /// <summary>
        /// 记录API调用失败日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="apiName">API名称</param>
        /// <param name="errorCode">错误代码</param>
        /// <param name="errorMessage">错误消息</param>
        /// <param name="duration">耗时</param>
        /// <param name="exception">异常（可选）</param>
        public static void LogApiCallFailed(this ILogger logger, string apiName, string errorCode, string errorMessage, 
            TimeSpan duration, Exception? exception = null)
        {
            if (exception != null)
            {
                logger.LogError(exception, "企业微信API调用失败 - API: {ApiName}, 错误代码: {ErrorCode}, 错误消息: {ErrorMessage}, 耗时: {Duration}ms", 
                    apiName, errorCode, errorMessage, duration.TotalMilliseconds);
            }
            else
            {
                logger.LogWarning("企业微信API调用失败 - API: {ApiName}, 错误代码: {ErrorCode}, 错误消息: {ErrorMessage}, 耗时: {Duration}ms", 
                    apiName, errorCode, errorMessage, duration.TotalMilliseconds);
            }
        }

        #endregion

        #region 缓存操作日志

        /// <summary>
        /// 记录缓存命中日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="cacheType">缓存类型</param>
        public static void LogCacheHit(this ILogger logger, string cacheKey, string cacheType)
        {
            logger.LogDebug("缓存命中 - 键: {CacheKey}, 类型: {CacheType}", cacheKey, cacheType);
        }

        /// <summary>
        /// 记录缓存未命中日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="cacheType">缓存类型</param>
        public static void LogCacheMiss(this ILogger logger, string cacheKey, string cacheType)
        {
            logger.LogDebug("缓存未命中 - 键: {CacheKey}, 类型: {CacheType}", cacheKey, cacheType);
        }

        /// <summary>
        /// 记录缓存设置日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="cacheType">缓存类型</param>
        /// <param name="expiryTime">过期时间</param>
        public static void LogCacheSet(this ILogger logger, string cacheKey, string cacheType, TimeSpan expiryTime)
        {
            logger.LogDebug("设置缓存 - 键: {CacheKey}, 类型: {CacheType}, 过期时间: {ExpiryTime}", 
                cacheKey, cacheType, expiryTime);
        }

        /// <summary>
        /// 记录缓存清除日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="cacheKey">缓存键</param>
        /// <param name="cacheType">缓存类型</param>
        public static void LogCacheClear(this ILogger logger, string cacheKey, string cacheType)
        {
            logger.LogInformation("清除缓存 - 键: {CacheKey}, 类型: {CacheType}", cacheKey, cacheType);
        }

        #endregion

        #region 配置和初始化日志

        /// <summary>
        /// 记录配置验证日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="isValid">是否有效</param>
        /// <param name="errors">错误列表</param>
        public static void LogConfigurationValidation(this ILogger logger, bool isValid, IEnumerable<string>? errors = null)
        {
            if (isValid)
            {
                logger.LogInformation("企业微信配置验证成功");
            }
            else
            {
                var errorList = errors?.ToList() ?? new List<string>();
                logger.LogError("企业微信配置验证失败 - 错误: {Errors}", string.Join("; ", errorList));
            }
        }

        /// <summary>
        /// 记录服务初始化日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="serviceName">服务名称</param>
        /// <param name="isSuccess">是否成功</param>
        /// <param name="duration">初始化耗时</param>
        public static void LogServiceInitialization(this ILogger logger, string serviceName, bool isSuccess, TimeSpan duration)
        {
            if (isSuccess)
            {
                logger.LogInformation("服务初始化成功 - 服务: {ServiceName}, 耗时: {Duration}ms", 
                    serviceName, duration.TotalMilliseconds);
            }
            else
            {
                logger.LogError("服务初始化失败 - 服务: {ServiceName}, 耗时: {Duration}ms", 
                    serviceName, duration.TotalMilliseconds);
            }
        }

        #endregion

        #region 安全相关日志

        /// <summary>
        /// 记录签名验证日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="isValid">验证结果</param>
        /// <param name="signature">签名（脱敏）</param>
        /// <param name="clientIp">客户端IP</param>
        public static void LogSignatureValidation(this ILogger logger, bool isValid, string signature, string clientIp)
        {
            var maskedSignature = MaskSensitiveData(signature);
            if (isValid)
            {
                logger.LogInformation("签名验证成功 - 签名: {Signature}, 客户端IP: {ClientIp}", maskedSignature, clientIp);
            }
            else
            {
                logger.LogWarning("签名验证失败 - 签名: {Signature}, 客户端IP: {ClientIp}", maskedSignature, clientIp);
            }
        }

        /// <summary>
        /// 记录可疑活动日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="activity">活动描述</param>
        /// <param name="clientIp">客户端IP</param>
        /// <param name="userAgent">用户代理</param>
        /// <param name="additionalInfo">附加信息</param>
        public static void LogSuspiciousActivity(this ILogger logger, string activity, string clientIp, 
            string? userAgent = null, object? additionalInfo = null)
        {
            logger.LogWarning("检测到可疑活动 - 活动: {Activity}, 客户端IP: {ClientIp}, 用户代理: {UserAgent}, 附加信息: {AdditionalInfo}", 
                activity, clientIp, userAgent ?? "未知", additionalInfo);
        }

        #endregion

        #region 性能监控日志

        /// <summary>
        /// 记录性能指标日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="operation">操作名称</param>
        /// <param name="duration">耗时</param>
        /// <param name="memoryUsage">内存使用量（字节）</param>
        /// <param name="additionalMetrics">附加指标</param>
        public static void LogPerformanceMetrics(this ILogger logger, string operation, TimeSpan duration, 
            long? memoryUsage = null, Dictionary<string, object>? additionalMetrics = null)
        {
            var metrics = new Dictionary<string, object>
            {
                ["Duration"] = duration.TotalMilliseconds,
                ["MemoryUsage"] = memoryUsage ?? 0
            };

            if (additionalMetrics != null)
            {
                foreach (var metric in additionalMetrics)
                {
                    metrics[metric.Key] = metric.Value;
                }
            }

            logger.LogInformation("性能指标 - 操作: {Operation}, 指标: {Metrics}", operation, metrics);
        }

        /// <summary>
        /// 记录慢查询日志
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="operation">操作名称</param>
        /// <param name="duration">耗时</param>
        /// <param name="threshold">阈值</param>
        /// <param name="parameters">参数</param>
        public static void LogSlowOperation(this ILogger logger, string operation, TimeSpan duration, 
            TimeSpan threshold, object? parameters = null)
        {
            logger.LogWarning("检测到慢操作 - 操作: {Operation}, 耗时: {Duration}ms, 阈值: {Threshold}ms, 参数: {Parameters}", 
                operation, duration.TotalMilliseconds, threshold.TotalMilliseconds, parameters);
        }

        #endregion

        #region 辅助方法

        /// <summary>
        /// 脱敏敏感数据
        /// </summary>
        /// <param name="data">原始数据</param>
        /// <param name="visibleLength">可见长度</param>
        /// <returns>脱敏后的数据</returns>
        private static string MaskSensitiveData(string data, int visibleLength = 6)
        {
            if (string.IsNullOrEmpty(data))
                return "[空]";

            if (data.Length <= visibleLength)
                return new string('*', data.Length);

            var visiblePart = data.Substring(0, Math.Min(visibleLength, data.Length));
            var maskedPart = new string('*', Math.Max(0, data.Length - visibleLength));
            return visiblePart + maskedPart;
        }

        /// <summary>
        /// 创建性能监控作用域
        /// </summary>
        /// <param name="logger">日志记录器</param>
        /// <param name="operation">操作名称</param>
        /// <returns>性能监控作用域</returns>
        public static IDisposable BeginPerformanceScope(this ILogger logger, string operation)
        {
            return new PerformanceScope(logger, operation);
        }

        #endregion
    }

    /// <summary>
    /// 性能监控作用域
    /// </summary>
    public class PerformanceScope : IDisposable
    {
        private readonly ILogger _logger;
        private readonly string _operation;
        private readonly Stopwatch _stopwatch;
        private readonly long _initialMemory;
        private bool _disposed = false;

        public PerformanceScope(ILogger logger, string operation)
        {
            _logger = logger;
            _operation = operation;
            _stopwatch = Stopwatch.StartNew();
            _initialMemory = GC.GetTotalMemory(false);
        }

        public void Dispose()
        {
            if (!_disposed)
            {
                _stopwatch.Stop();
                var finalMemory = GC.GetTotalMemory(false);
                var memoryDelta = finalMemory - _initialMemory;

                _logger.LogPerformanceMetrics(_operation, _stopwatch.Elapsed, memoryDelta);

                // 如果操作耗时超过1秒，记录为慢操作
                if (_stopwatch.Elapsed.TotalSeconds > 1)
                {
                    _logger.LogSlowOperation(_operation, _stopwatch.Elapsed, TimeSpan.FromSeconds(1));
                }

                _disposed = true;
            }
        }
    }

    /// <summary>
    /// 企业微信日志提供程序
    /// </summary>
    public class WeChatLoggerProvider : ILoggerProvider
    {
        private readonly ConcurrentDictionary<string, WeChatLogger> _loggers = new();

        public ILogger CreateLogger(string categoryName)
        {
            return _loggers.GetOrAdd(categoryName, name => new WeChatLogger(name));
        }

        public void Dispose()
        {
            _loggers.Clear();
        }
    }

    /// <summary>
    /// 企业微信日志记录器
    /// </summary>
    public class WeChatLogger : ILogger
    {
        private readonly string _categoryName;

        public WeChatLogger(string categoryName)
        {
            _categoryName = categoryName;
        }

        public IDisposable BeginScope<TState>(TState state)
        {
            return NullScope.Instance;
        }

        public bool IsEnabled(LogLevel logLevel)
        {
            return logLevel >= LogLevel.Information;
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
        {
            if (!IsEnabled(logLevel))
                return;

            var message = formatter(state, exception);
            
            // 这里可以添加自定义的日志处理逻辑
            // 例如：发送到特定的日志系统、添加特殊格式等
            Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] [{logLevel}] [{_categoryName}] {message}");
            
            if (exception != null)
            {
                Console.WriteLine(exception.ToString());
            }
        }

        private class NullScope : IDisposable
        {
            public static NullScope Instance { get; } = new();
            public void Dispose() { }
        }
    }
}